﻿using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using VisionCloud.Core.Model.Ms;
using VisionCloud.Domain.Common;
using VisionCloud.Domain.DtoModel.Applet.RequestDto;
using VisionCloud.Domain.DtoModel.Applet.ResponseDto;
using VisionCloud.Domain.Extension;
using VisionCloud.Domain.Repository.Interface.Sys;
using VisionCloud.Domain.UnitOfWork;
using VisionCloud.Utility;

namespace VisionCloud.Service.Applet
{
    public class UserService
    {
        public IUnitOfWork UnitOfWork { get; set; }
        public ISysUserRepository SysUserRepository { get; set; }

        public ISysUserDeviceTraceRepository SysUserDeviceTraceRepository { get; set; }

        private readonly Guid current_user_id = OperatorProvider.Get().Id;

        public async Task<UserInfoDto> GetCurUserInfo() => await SysUserRepository.GetAll()
                                                                .Select(x => new UserInfoDto
                                                                {
                                                                    Id = x.YunUserGuid,
                                                                    Name = x.Name,
                                                                    CompanyName = x.Company,
                                                                    Department = x.Department,
                                                                    Email = x.Email,
                                                                    PhoneNumber = x.PhoneNumber,
                                                                    Position = x.Position,
                                                                    RoleName = x.RoleNameList,
                                                                    UserType = (int)x.UserType,
                                                                    IsEnableModeling = x.EnabledModeling,
                                                                    EnabledExternalWall = x.EnabledExternalWall,
                                                                    EnabledAppletCollecting = x.EnabledAppletCollecting,
                                                                }).FirstOrDefaultAsync(x => x.Id == current_user_id);

        public async Task<DeviceInfosDto> GetCurUserDevices(PageRequest condition)
        {
            var result = new DeviceInfosDto
            {
                Total = 0,
                DeviceInfos = new List<DeviceLastAddressView>()
            };

            var query = SysUserDeviceTraceRepository.QueryDeviceByUser(current_user_id).WhereIf(!string.IsNullOrWhiteSpace(condition.Keywords), x => x.DeviceNumber.Contains(condition.Keywords));
            query = condition.IsAscend ? query.OrderBy(x => x.DeviceNumber) : query.OrderByDescending(x => x.DeviceNumber);
            var count = await query?.CountAsync();
            if (count > 0)
            {
                var skipValue = (condition.Page - 1) * condition.PageSize;

                result.Total = count;

                result.DeviceInfos = await query.Skip(skipValue).Take(condition.PageSize).ToListAsync();
            }

            return result;
        }

        public async Task<DateTime> UpdateDeviceAddress(DeviceLocationDto deviceLocation)
        {
            var addressInfo = deviceLocation.AddressInfo;
            var lastUpdatedDate = DateTime.UtcNow.AddHours(8);
            SysUserDeviceTraceRepository.Add(new Core.Model.Sys.SysUserDeviceTrace
            {
                UserId = current_user_id,
                DeviceId = deviceLocation.DeviceId,
                CreatedDate = lastUpdatedDate,
                Address = addressInfo.Address,
                CreatedBy = current_user_id,
                DeviceNumber = deviceLocation.DeviceNumber,
                Latitude = deviceLocation.Latitude,
                Longitude = deviceLocation.Longitude,
                Type = 0,
                Province = addressInfo.Province,
                City = addressInfo.City,
                District = addressInfo.District,
                Township = addressInfo.Township,
            }, false);
            await UnitOfWork.SaveChangesAsync();

            return lastUpdatedDate;
        }

        public async Task<AddressInfo> GetAddress(LocationDto locaton)
        {
            var addressInfo = await AddressHelper.GetAddressFromLocation(locaton.Latitude, locaton.Longitude);
            return new AddressInfo
            {
                Address = addressInfo.Address,
                Province = addressInfo.Province,
                City = addressInfo.City,
                District = addressInfo.District,
                Township = addressInfo.Twon
            };
        }
    }
}